package com.hyt.it.ogt.ykcj.service.grade.impl;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.hyt.it.ogt.ykcj.common.constant.Constants;
import com.hyt.it.ogt.ykcj.common.core.domain.AjaxResult;
import com.hyt.it.ogt.ykcj.common.core.domain.entity.SysDictData;
import com.hyt.it.ogt.ykcj.common.enums.AnalysisType;
import com.hyt.it.ogt.ykcj.common.enums.BizErrorCode;
import com.hyt.it.ogt.ykcj.common.enums.ExamTypeEnums;
import com.hyt.it.ogt.ykcj.common.enums.ExportType;
import com.hyt.it.ogt.ykcj.common.exception.CustomException;
import com.hyt.it.ogt.ykcj.common.utils.Arith;
import com.hyt.it.ogt.ykcj.common.utils.DateUtils;
import com.hyt.it.ogt.ykcj.common.utils.IdUtils;
import com.hyt.it.ogt.ykcj.common.utils.MathUtils;
import com.hyt.it.ogt.ykcj.common.utils.StringUtils;
import com.hyt.it.ogt.ykcj.common.utils.poi.ExcelUtil;
import com.hyt.it.ogt.ykcj.common.utils.reflect.ReflectUtils;
import com.hyt.it.ogt.ykcj.domain.exam.ChangedExamInfo;
import com.hyt.it.ogt.ykcj.domain.exam.ExamInfo;
import com.hyt.it.ogt.ykcj.domain.exam.ExamStemInfo;
import com.hyt.it.ogt.ykcj.domain.exam.ExamSubjectInfo;
import com.hyt.it.ogt.ykcj.domain.exam.ExamSubjectNameConfig;
import com.hyt.it.ogt.ykcj.domain.grade.GradeAnalysisData;
import com.hyt.it.ogt.ykcj.domain.grade.ServantExamineeInfo;
import com.hyt.it.ogt.ykcj.domain.grade.ServantInterviewAnalysisData;
import com.hyt.it.ogt.ykcj.domain.grade.ServantPassAnalysisData;
import com.hyt.it.ogt.ykcj.domain.grade.ServantSubjectPtGradeAnalysisData;
import com.hyt.it.ogt.ykcj.domain.vo.ExportParamVo;
import com.hyt.it.ogt.ykcj.domain.vo.GradeAnalysisDataVo;
import com.hyt.it.ogt.ykcj.domain.vo.GradeAnalysisRsp;
import com.hyt.it.ogt.ykcj.domain.vo.GradeAnalysisTotalDataVo;
import com.hyt.it.ogt.ykcj.domain.vo.QueryExamineeGradeVo;
import com.hyt.it.ogt.ykcj.domain.vo.export.ExportAnalysisDataBaseVo;
import com.hyt.it.ogt.ykcj.domain.vo.export.ExportAreaAnalysisDataVo;
import com.hyt.it.ogt.ykcj.domain.vo.export.ExportExamRateAnalysisDataVo;
import com.hyt.it.ogt.ykcj.domain.vo.export.ExportPassRateAnalysisDataVo;
import com.hyt.it.ogt.ykcj.domain.vo.export.ExportSubjectAnalysisDataVo;
import com.hyt.it.ogt.ykcj.mapper.exam.ChangedExamInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.exam.ExamInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.exam.ExamStemInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.exam.ExamSubjectInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.exam.ExamSubjectNameConfigMapper;
import com.hyt.it.ogt.ykcj.mapper.grade.ExamineeGradeInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.grade.ExamineeSubjectGradeInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.grade.GradeAnalysisDataMapper;
import com.hyt.it.ogt.ykcj.mapper.grade.ServantExamineeInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.grade.ServantExamineeSubjectGradeMapper;
import com.hyt.it.ogt.ykcj.mapper.grade.ServantInterviewAnalysisDataMapper;
import com.hyt.it.ogt.ykcj.mapper.grade.ServantPassAnalysisDataMapper;
import com.hyt.it.ogt.ykcj.mapper.system.SysDictDataMapper;
import com.hyt.it.ogt.ykcj.service.grade.IGradeAnalysisDataService;
import com.hyt.it.ogt.ykcj.service.grade.IServantSubjectPtGradeAnalysisDataService;

/**
 * 考试成绩数据分析Service业务层处理
 * 
 * @author admin
 * @date 2021-06-24
 */
@Service
public class GradeAnalysisDataServiceImpl implements IGradeAnalysisDataService {
    private static final Logger log = LoggerFactory.getLogger(GradeAnalysisDataServiceImpl.class);

    @Autowired
    private GradeAnalysisDataMapper gradeAnalysisDataMapper;

    @Autowired
    private ExamInfoMapper examInfoMapper;

    @Autowired
    private ExamineeGradeInfoMapper gradeInfoMapper;

    @Autowired
    private ServantExamineeInfoMapper servantExamineeInfoMapper;

    @Autowired
    private ExamineeSubjectGradeInfoMapper subjectGradeInfoMapper;

    @Autowired
    private ServantExamineeSubjectGradeMapper servantExamineeSubjectGradeMapper;
    @Autowired
    private SysDictDataMapper dictDataMapper;

    @Autowired
    private ExamSubjectInfoMapper subjectInfoMapper;

    @Autowired
    private ExamSubjectNameConfigMapper subjectNameConfigMapper;

    @Autowired
    private ChangedExamInfoMapper changedExamInfoMapper;

    @Autowired
    private ExamStemInfoMapper examStemInfoMapper;


    @Autowired
    private IServantSubjectPtGradeAnalysisDataService servantSubjectPtGradeAnalysisDataService;
    @Autowired
    private ServantPassAnalysisDataMapper servantPassAnalysisDataMapper;

    @Autowired
    private ServantInterviewAnalysisDataMapper servantInterviewAnalysisDataMapper;

    /**
     * 查询考试成绩数据分析
     *
     * @param analysisId 考试成绩数据分析ID
     * @return 考试成绩数据分析
     */
    @Override
    public GradeAnalysisData selectGradeAnalysisDataById(String analysisId) {
        return gradeAnalysisDataMapper.selectGradeAnalysisDataById(analysisId);
    }

    /**
     * 查询考试成绩数据分析列表
     *
     * @param gradeAnalysisData 考试成绩数据分析
     * @return 考试成绩数据分析
     */
    @Override
    public List<GradeAnalysisData> selectGradeAnalysisDataList(GradeAnalysisData gradeAnalysisData) {
        return gradeAnalysisDataMapper.selectGradeAnalysisDataList(gradeAnalysisData);
    }

    /**
     * 新增考试成绩数据分析
     *
     * @param gradeAnalysisData 考试成绩数据分析
     * @return 结果
     */
    @Override
    public int insertGradeAnalysisData(GradeAnalysisData gradeAnalysisData) {
        gradeAnalysisData.setCreateTime(DateUtils.getNowDate());
        return gradeAnalysisDataMapper.insertGradeAnalysisData(gradeAnalysisData);
    }

    /**
     * 修改考试成绩数据分析
     *
     * @param gradeAnalysisData 考试成绩数据分析
     * @return 结果
     */
    @Override
    public int updateGradeAnalysisData(GradeAnalysisData gradeAnalysisData) {
        gradeAnalysisData.setUpdateTime(DateUtils.getNowDate());
        return gradeAnalysisDataMapper.updateGradeAnalysisData(gradeAnalysisData);
    }

    /**
     * 批量删除考试成绩数据分析
     *
     * @param analysisIds 需要删除的考试成绩数据分析ID
     * @return 结果
     */
    @Override
    public int deleteGradeAnalysisDataByIds(String[] analysisIds) {
        return gradeAnalysisDataMapper.deleteGradeAnalysisDataByIds(analysisIds);
    }

    /**
     * 删除考试成绩数据分析信息
     *
     * @param analysisId 考试成绩数据分析ID
     * @return 结果
     */
    @Override
    public int deleteGradeAnalysisDataById(String analysisId) {
        return gradeAnalysisDataMapper.deleteGradeAnalysisDataById(analysisId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void gradeDataStatistics() {
        // 先查出来有多少考试有成绩信息，再查每个考试有多少年份。在循环统计
        List<ExamInfo> examInfoList = examInfoMapper.selectChangedExamInfoList();
        // 查询需要更新的考试成绩信息
        if (CollectionUtils.isEmpty(examInfoList)) {
            log.info("暂无考试信息,不执行统计操作");
            return;
        }

        // 考虑到一个考试一年可能多次考试
        for (ExamInfo examInfo : examInfoList) {
            // 先删除对应的考试记录
            String examId = examInfo.getId();
            String examNameConfigId = examInfo.getExamNameConfigId();
            String examYear = examInfo.getYear();
            gradeAnalysisDataMapper.deleteGradeAnalysisDataByExamId(examId);
            //专业技术类考生
            if (ExamTypeEnums.EXPERTISE.getCode().equals(examInfo.getExamType())) {
                // 先获取考试对应的所有考生总数
                long registrationNum = gradeInfoMapper.countExamineeByExamId(examId);
                // 实际考试人数
                long examineeNum = subjectGradeInfoMapper.countActualExamNumByExamId(examId);
                //总的合格人数
                long totalPassNum = gradeInfoMapper.seleExamineeCountByPass(examId);
                if (registrationNum > 0) {
                    countTotalData(examId, examYear, AnalysisType.ANSLYSIS_TYPE_TOTAL, examNameConfigId, registrationNum, examineeNum);
                    countSubjectData(examId, examYear, AnalysisType.ANSLYSIS_TYPE_SUBJECT, examNameConfigId, registrationNum, examineeNum);
                    countSexData(examId, examYear, AnalysisType.ANSLYSISE_TYPE_SEX, examNameConfigId, registrationNum, examineeNum, totalPassNum);
                    countAreaData(examId, examYear, AnalysisType.ANSLYSIS_TYPE_AREA, examNameConfigId);
                    countAgeData(examId, examYear, AnalysisType.ANSLYSIS_TYPE_AGE, examNameConfigId, registrationNum, examineeNum);
                }
            } else {
                //数据清除
                deleteServantExamData(examId);
                //公务员考试统计
                servantExamStatistics(examId, examYear, examNameConfigId);
            }
            updateChangedExamInfoTime(examId);
        }
    }

    /**
     * 清除公务员分析数据
     *
     * @param examId
     */
    private void deleteServantExamData(String examId) {
        if (StringUtils.isEmpty(examId)) {
            return;
        }
        ServantSubjectPtGradeAnalysisData spg = new ServantSubjectPtGradeAnalysisData();
        spg.setExamId(examId);
        servantSubjectPtGradeAnalysisDataService.delete(spg);
        ServantPassAnalysisData pass = new ServantPassAnalysisData();
        pass.setExamId(examId);
        servantPassAnalysisDataMapper.delete(pass);
        ServantInterviewAnalysisData interview = new ServantInterviewAnalysisData();
        interview.setExamId(examId);
        servantInterviewAnalysisDataMapper.delete(interview);
    }

    /**
     * 公务员考试统计
     *
     * @param examId
     * @param examYear
     */
    private void servantExamStatistics(String examId, String examYear, String examNameConfigId) {
        //获得职位层级
        SysDictData tmp = new SysDictData();
        tmp.setDictType("position_tier");
        List<SysDictData> positions = dictDataMapper.selectDictDataList(tmp);
        if (CollectionUtils.isEmpty(positions)) {
            log.warn("未找到职位层级对应的字典信息");
            return;
        }
        tmp.setDictType("position_category");
        List<SysDictData> positionCategorys = dictDataMapper.selectDictDataList(tmp);
        if (CollectionUtils.isEmpty(positions)) {
            log.warn("未找到职位类别的字典信息");
            return;
        }
        // 先获取考试对应的所有考生总数
        ServantExamineeInfo servantExamineeInfo = new ServantExamineeInfo();
        servantExamineeInfo.setExamId(examId);
        long registrationNum = servantExamineeInfoMapper.selectServantExamineeInfoCount(servantExamineeInfo).longValue(); // 统计实际报名人数
        // 实际考试人数
        long examineeNum = servantExamineeSubjectGradeMapper.countActualExamNumByExamId(examId);
        //总的合格人数
        servantExamineeInfo.setQualifiedStatus("Y");
        long totalPassNum = servantExamineeInfoMapper.selectServantExamineeInfoCount(servantExamineeInfo).longValue(); // 统计通过人数-- 达合格分数线进入面试
        if (registrationNum > 0) {
            GradeAnalysisData gradeAnalysisData = initGradeAnalysisDataInfo(
                    AnalysisType.ANSLYSIS_TYPE_TOTAL, examNameConfigId, examYear, registrationNum, examineeNum, totalPassNum, null, examId);
            gradeAnalysisDataMapper.insertGradeAnalysisData(gradeAnalysisData);
        }
        //按性别统计合格率
        countSexData(examId, examYear, AnalysisType.ANSLYSISE_TYPE_SEX, examNameConfigId, registrationNum, examineeNum, totalPassNum);
        //按科目、职位层级、题型统计得分及正确率情况
        servantExamStatisticsSubject(examId, examYear, examNameConfigId, positions);

        //按职位层级、职位类别统计参考及合格情况
        servantPassAnalysis(examId, examYear, examNameConfigId, positions, positionCategorys);

        //按职位层级、职位类别统计面试及招录人数情况
        servantInterviewAnalysis(examId, examYear, examNameConfigId, positions, positionCategorys);
    }


    /**
     * 按职位层级、职位类别统计面试及招录人数
     *
     * @param examId
     * @param examYear
     * @param examNameConfigId
     * @param positions
     * @param positionCategorys
     */
    private void servantInterviewAnalysis(String examId, String examYear,
                                          String examNameConfigId, List<SysDictData> positions, List<SysDictData> positionCategorys) {
        Map paramMap = new HashMap(2);
        paramMap.put("examId", examId);
        List<ServantInterviewAnalysisData> datas = servantInterviewAnalysisDataMapper.servantInterviewAnalysis(paramMap);
        if (CollectionUtils.isEmpty(datas)) {
            return;
        }
        Map<String, ServantInterviewAnalysisData> dataMap = datas.stream().collect(Collectors.toMap(ServantInterviewAnalysisData::getPositionTierAndZwlb, a -> a, (k1, k2) -> k1));
        for (SysDictData sysDictData : positions) {
            String positionTier = sysDictData.getDictValue();
            String positionTierName = sysDictData.getDictLabel();
            for (SysDictData sysDictData1 : positionCategorys) {
                String positionCategory = sysDictData1.getDictValue();
                String positionCategoryName = sysDictData1.getDictLabel();
                ServantInterviewAnalysisData data = dataMap.get(positionTier + positionCategory);
                if (data == null) {
                    data = new ServantInterviewAnalysisData();
                    data.setId(IdUtils.generateId());
                    data.setExamYear(examYear);
                    data.setExamId(examId);
                    data.setExamNameConfigId(examNameConfigId);
                    data.setPositionTier(positionTier);
                    data.setZwlb(positionCategory);
                    data.setPositionTierName(positionTierName);
                    data.setZwlbName(positionCategoryName);
                    servantInterviewAnalysisDataMapper.insertServantInterviewAnalysisData(data);
                } else {
                    data.setId(IdUtils.generateId());
                    data.setExamYear(examYear);
                    data.setExamId(examId);
                    data.setExamNameConfigId(examNameConfigId);
                    data.setPositionTierName(positionTierName);
                    data.setZwlbName(positionCategoryName);
                    servantInterviewAnalysisDataMapper.insertServantInterviewAnalysisData(data);
                }

            }
        }
    }


    /**
     * 按职位层级、职位类别统计参考及合格情况
     *
     * @param examId
     * @param examYear
     * @param examNameConfigId
     * @param positions
     */
    private void servantPassAnalysis(String examId, String examYear,
                                     String examNameConfigId, List<SysDictData> positions, List<SysDictData> positionCategorys) {
        ServantPassAnalysisData analysisData = new ServantPassAnalysisData();
        analysisData.setExamId(examId);
        servantPassAnalysisDataMapper.delete(analysisData);
        Map paramMap = new HashMap(2);
        paramMap.put("examId", examId);
        List<ServantPassAnalysisData> datas = servantPassAnalysisDataMapper.getPassGradeInfoByZw(paramMap);
        if (CollectionUtils.isEmpty(datas)) {
            return;
        }
        Map<String, List<ServantPassAnalysisData>> dataMap = datas.stream().collect(Collectors.groupingBy(d -> d.getPositionTier() + d.getZwlb()));
        for (SysDictData sysDictData : positions) {
            String positionTier = sysDictData.getDictValue();
            String positionTierName = sysDictData.getDictLabel();
            for (SysDictData sysDictData1 : positionCategorys) {
                String positionCategory = sysDictData1.getDictValue();
                String positionName = sysDictData1.getDictLabel();
                List<ServantPassAnalysisData> groupBys = dataMap.get(positionTier + positionCategory);
                if (CollectionUtils.isEmpty(groupBys)) {
                    ServantPassAnalysisData data = new ServantPassAnalysisData().init(examYear, examNameConfigId, positionTier, positionCategory);
                    data.setPositionTierName(positionTierName);
                    data.setExamId(examId);
                    data.setZwlbName(positionName);
                    servantPassAnalysisDataMapper.insertServantPassAnalysisData(data);
                } else {
                    for (ServantPassAnalysisData data : groupBys) {
                        data.setId(IdUtils.generateId());
                        data.setExamYear(examYear);
                        data.setExamId(examId);
                        data.setExamNameConfigId(examNameConfigId);
                        data.setPositionTierName(positionTierName);
                        data.setZwlbName(positionName);

                        servantPassAnalysisDataMapper.insertServantPassAnalysisData(data);
                    }
                }
            }
        }
    }

    /**
     * 按科目、机构层级、题型统计得分及正确率情况
     *
     * @param examId
     * @param examYear
     * @param examNameConfigId
     * @param positions
     */
    private void servantExamStatisticsSubject(String examId, String examYear, String examNameConfigId,
                                              List<SysDictData> positions) {
        List<ExamSubjectInfo> subjectInfos = subjectInfoMapper.selectExamSubjectInfoListById(examId);
        List<ServantSubjectPtGradeAnalysisData> gradeAnalysisData = new ArrayList<>();
        for (ExamSubjectInfo subjectInfo : subjectInfos) {
            String subjectId = subjectInfo.getId();
            //获取科目对应题型
            ExamStemInfo stemInfo = new ExamStemInfo();
            stemInfo.setSubjectId(subjectId);
            List<ExamStemInfo> examStemInfos = examStemInfoMapper.selectExamStemInfoList(stemInfo);
            for (ExamStemInfo examStemInfo : examStemInfos) {
                String stemId = examStemInfo.getId();
                for (SysDictData sysDictData : positions) {
                    String positionTier = sysDictData.getDictValue();
                    String positionTierName = sysDictData.getDictLabel();
                    Map paramMap = new HashMap();
                    paramMap.put("examId", examId);
                    paramMap.put("subjectId", subjectId);
                    paramMap.put("stemId", stemId);
                    paramMap.put("positionTier", positionTier);
                    //统计男、女 总平均分
                    Double avgScore = servantExamineeSubjectGradeMapper.getAvgScore(paramMap);
                    paramMap.put("sex", "男");
                    Double maleAvgScore = servantExamineeSubjectGradeMapper.getAvgScore(paramMap);
                    paramMap.put("sex", "女");
                    Double femaleAvgScore = servantExamineeSubjectGradeMapper.getAvgScore(paramMap);
                    //统计男、女、总正确率
                    Double rightRate = examStemInfo.getTotalPoints().doubleValue() != 0 ? Arith.div(avgScore, examStemInfo.getTotalPoints().doubleValue(), 4) : 0;
                    Double maleRightRate = examStemInfo.getTotalPoints().doubleValue() != 0 ? Arith.div(maleAvgScore, examStemInfo.getTotalPoints().doubleValue(), 4) : 0;
                    Double femaleRightRate = examStemInfo.getTotalPoints().doubleValue() != 0 ? Arith.div(femaleAvgScore, examStemInfo.getTotalPoints().doubleValue(), 4) : 0;

                    ServantSubjectPtGradeAnalysisData data = new ServantSubjectPtGradeAnalysisData();
                    data.setId(IdUtils.generateId());
                    data.setExamId(examId);
                    data.setSubjectId(subjectId);
                    data.setExamYear(examYear);
                    data.setExamNameConfigId(examNameConfigId);
                    data.setExamStemId(stemId);
                    data.setExamStemName(examStemInfo.getName());
                    data.setPositionTier(positionTier);
                    data.setPositionTierName(positionTierName);
                    data.setAvgScore(MathUtils.setScale(avgScore, 2));
                    data.setMaleAvgScore(MathUtils.setScale(maleAvgScore, 2));
                    data.setFemaleAvgScore(MathUtils.setScale(femaleAvgScore, 2));
                    data.setRightRate(MathUtils.setScale(rightRate, 4));
                    data.setMaleRightRate(MathUtils.setScale(maleRightRate, 4));
                    data.setFemaleRightRate(MathUtils.setScale(femaleRightRate, 4));
                    gradeAnalysisData.add(data);
                }
            }
        }
        //批量插入
        if (CollectionUtils.isNotEmpty(gradeAnalysisData)) {
            servantSubjectPtGradeAnalysisDataService.batchInsertServantSubjectPtGradeAnalysisData(gradeAnalysisData);
        }
    }

    /**
     * 更新考试时间
     *
     * @param examId
     */
    private void updateChangedExamInfoTime(String examId) {
        ChangedExamInfo changedExamInfo = new ChangedExamInfo();
        changedExamInfo.setExamId(examId);
        changedExamInfo.setStatisticsEndTime(DateUtils.getNowDate());
        changedExamInfoMapper.updateChangedExamInfo(changedExamInfo);
    }

    /**
     * 统计总数据
     *
     * @param examId
     * @param year
     * @param type
     * @param examNameConfigId
     * @param registrationNum
     * @param examineeNum
     */
    private void countTotalData(String examId, String year, AnalysisType type, String examNameConfigId, long registrationNum, long examineeNum) {

        // 合格数
        long totalPass = gradeInfoMapper.countPassByExamId(examId, null, null);


        GradeAnalysisData gradeAnalysisData = initGradeAnalysisDataInfo(type, examNameConfigId, year, registrationNum, examineeNum, totalPass, null, examId);
        gradeAnalysisDataMapper.insertGradeAnalysisData(gradeAnalysisData);
    }

    /**
     * 根据科目统计
     *
     * @param examId
     * @param year
     * @param type
     * @param examNameConfigId
     * @param registrationNum
     * @param examineeNum
     */
    private void countSubjectData(String examId, String year, AnalysisType type, String examNameConfigId, long registrationNum, long examineeNum) {
        List<GradeAnalysisData> gradeAnalysisDataList = new ArrayList<>();
        // 统计科目合格考生信息
        List<GradeAnalysisTotalDataVo> passList = subjectGradeInfoMapper.countSubjectPassNum(examId, Constants.PASS_FLAT_Y, AnalysisType.ANSLYSIS_TYPE_SUBJECT.getFieldName());
        if (!CollectionUtils.isEmpty(passList)) {
            for (GradeAnalysisTotalDataVo vo : passList) {
                GradeAnalysisData gradeAnalysisData = initGradeAnalysisDataInfo(type, examNameConfigId, year, registrationNum, examineeNum, vo.getTotalNum(), vo.getSubjectId(), examId);
                gradeAnalysisDataList.add(gradeAnalysisData);
            }
            gradeAnalysisDataMapper.batchInsertGradeAnalysisData(gradeAnalysisDataList);
        }
    }

    /**
     * 根据性别统计
     *
     * @param examId
     * @param year
     * @param type
     * @param examNameConfigId
     * @param registrationNum
     * @param examineeNum
     */
    private void countSexData(String examId, String year, AnalysisType type, String examNameConfigId, long registrationNum, long examineeNum, long totalPassNum) {
        // 插入列表
        List<GradeAnalysisData> gradeAnalysisDataList = new ArrayList<>();
        // 根据性别统计学生合格率
        List<GradeAnalysisTotalDataVo> passList = servantExamineeSubjectGradeMapper.countServantPassByExamIdAndSex(examId);
        if (!CollectionUtils.isEmpty(passList)) {
            for (GradeAnalysisTotalDataVo vo : passList) {
                GradeAnalysisData gradeAnalysisData = initGradeAnalysisDataInfo(type, examNameConfigId, year, registrationNum, examineeNum, vo.getTotalNum(), vo.getSex(), examId);
                //重置性别通过率
                gradeAnalysisData.setPassRate(getRate(totalPassNum, gradeAnalysisData.getPassNum()));
                gradeAnalysisDataList.add(gradeAnalysisData);
            }
            gradeAnalysisDataMapper.batchInsertGradeAnalysisData(gradeAnalysisDataList);
        }
    }

    /**
     * 根据地区统计，需要统计每个地区的报名人数、实际考试人数
     *
     * @param examId
     * @param year
     * @param type
     * @param examNameConfigId

     */
    private void countAreaData(String examId, String year, AnalysisType type, String examNameConfigId) {
        List<GradeAnalysisData> gradeAnalysisDataList = new ArrayList<>();
        // 根据地区统计学生报名数
        List<GradeAnalysisTotalDataVo> totalList = gradeInfoMapper.countExamineeByArea(examId);
        //Map<String,Long> totalMap = totalList.stream().collect(Collectors.toMap(GradeAnalysisTotalDataVo::getArea, GradeAnalysisTotalDataVo::getTotalNum));
        if (CollectionUtils.isEmpty(totalList)) {
            log.info("考试{}没有考生区域相关信息", examId);
        }
        // 根据地区统计学生实际考试
        List<GradeAnalysisTotalDataVo> catualList = gradeInfoMapper.countPassByExamIdAndType(examId, null, AnalysisType.ANSLYSIS_TYPE_AREA.getFieldName());
        Map<String, Long> actualMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(catualList)) {
            actualMap = catualList.stream().collect(Collectors.toMap(GradeAnalysisTotalDataVo::getArea, GradeAnalysisTotalDataVo::getTotalNum));
        }

        // 根据地区统计学生合格率
        List<GradeAnalysisTotalDataVo> passList = gradeInfoMapper.countPassByExamIdAndType(examId, Constants.PASS_FLAT_Y, AnalysisType.ANSLYSIS_TYPE_AREA.getFieldName());
        Map<String, Long> passMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(passList)) {
            passMap = passList.stream().collect(Collectors.toMap(GradeAnalysisTotalDataVo::getArea, GradeAnalysisTotalDataVo::getTotalNum));
        }
        if (CollectionUtils.isNotEmpty(totalList)) {
            for (GradeAnalysisTotalDataVo vo : totalList) {
                // 区域报名人数
                long registrationNum = vo.getTotalNum();
                Long passNum = 0L;
                long examineeNum = 0L;
                if (null != passMap.get(vo.getArea())) {
                    // 区域合格人数
                    passNum = passMap.get(vo.getArea());
                }
                if (null != actualMap.get(vo.getArea())) {
                    // 每个区域的实际考试人数
                    examineeNum = actualMap.get(vo.getArea());
                }
                GradeAnalysisData gradeAnalysisData = initGradeAnalysisDataInfo(type, examNameConfigId, year, registrationNum, examineeNum, passNum, vo.getArea(), examId);
                gradeAnalysisDataList.add(gradeAnalysisData);
            }
            gradeAnalysisDataMapper.batchInsertGradeAnalysisData(gradeAnalysisDataList);
        }
    }

    /**
     * 根据年龄段统计
     *
     * @param examId
     * @param year
     * @param type
     * @param examNameConfigId
     * @param registrationNum
     * @param examineeNum
     */
    private void countAgeData(String examId, String year, AnalysisType type, String examNameConfigId, long registrationNum, long examineeNum) {
        // 取出字典表中的年龄范围code
        SysDictData sysDictData = new SysDictData();
        sysDictData.setDictType("sys_age_range");
        List<SysDictData> sysDictDataList = dictDataMapper.selectDictDataList(sysDictData);
        if (CollectionUtils.isEmpty(sysDictDataList)) {
            log.info("未找到年龄区间段对应的字典信息");
            return;
        }

        List<GradeAnalysisData> gradeAnalysisDataList = new ArrayList<>();
        for (SysDictData data : sysDictDataList) {
            String label = data.getDictLabel();
            String[] ageArr = label.split("-");
            String startAge = null;
            String endAge = null;
            if (StringUtils.isNotEmpty(ageArr[0])) {
                startAge = ageArr[0];
            }
            if (ageArr.length > 1 && StringUtils.isNotEmpty(ageArr[1])) {
                endAge = ageArr[1];
            }
            // 获取年龄段的合格人数
            long passNum = gradeInfoMapper.countPassByExamId(examId, startAge, endAge);
            GradeAnalysisData gradeAnalysisData = initGradeAnalysisDataInfo(type, examNameConfigId, year, registrationNum, examineeNum, passNum, data.getDictValue(), examId);
            gradeAnalysisDataList.add(gradeAnalysisData);
        }
        gradeAnalysisDataMapper.batchInsertGradeAnalysisData(gradeAnalysisDataList);

    }

    /**
     * 获取合格率和通过率，四舍五入
     *
     * @param totalNum
     * @param actualNum
     * @return
     */
    private BigDecimal getRate(long totalNum, long actualNum) {
        BigDecimal rate = BigDecimal.valueOf(actualNum).divide(BigDecimal.valueOf(totalNum), 2, BigDecimal.ROUND_HALF_UP);
        return rate;
    }

    /**
     * 初始化需要插入的考试信息
     *
     * @param analysisType     统计类型
     * @param examNameConfigId 统计考试名称配置id
     * @param examYear         统计年份
     * @param registrationNum  总人数
     * @param examineeNum      实际考试人数
     * @param passNum          通过人数
     * @param fieldData        统计类型为total:null,subject：科目id,age:年龄区间code,sex:性别code,area:地名区'
     * @return
     */

    private GradeAnalysisData initGradeAnalysisDataInfo(AnalysisType analysisType, String examNameConfigId, String examYear, long registrationNum, long examineeNum, long passNum,
                                                        String fieldData, String examId) {
        GradeAnalysisData gradeAnalysisData = new GradeAnalysisData();
        gradeAnalysisData.setAnalysisId(IdUtils.generateId());
        gradeAnalysisData.setAnalysisType(analysisType.getCode());
        if (StringUtils.isNotEmpty(analysisType.getPropertyName())) {
            //反射设值
            ReflectUtils.invokeSetter(gradeAnalysisData, analysisType.getPropertyName(), fieldData);
        }
        gradeAnalysisData.setRegistrationNum(registrationNum);
        gradeAnalysisData.setExamineeNum(examineeNum);
        gradeAnalysisData.setPassNum(passNum);
        gradeAnalysisData.setExamRate(getRate(registrationNum, examineeNum));
        //适用于非性别分类
        gradeAnalysisData.setPassRate(getRate(registrationNum, passNum));
        gradeAnalysisData.setExamId(examId);
        gradeAnalysisData.setExamNameConfigId(examNameConfigId);
        gradeAnalysisData.setExamYear(examYear);
        gradeAnalysisData.setCreateTime(DateUtils.getNowDate());
        gradeAnalysisData.setUpdateTime(DateUtils.getNowDate());
        return gradeAnalysisData;
    }

    @Override
    public List<GradeAnalysisDataVo> getGradeAnalysisDataBySex(String examNameConfigId,
                                                               String examYear, String examId) {
        return gradeAnalysisDataMapper.selectGradeAnalysisDataListByIdAndYear(examNameConfigId, examYear, AnalysisType.ANSLYSISE_TYPE_SEX.getCode(), examId);
    }

    /**
     * 按性别统计最近五年通过及合格情况
     *
     * @param examNameConfigId
     * @param examYear
     * @param examId
     * @return
     */
    @Override
    public List<GradeAnalysisDataVo> getGradeAnalysisDataBySexYearList(String examNameConfigId,
                                                                       String examYear, String examId) {
        // 最近五年年份数据
        List<String> yearList = null;
        try {
            yearList = DateUtils.getLatestFiveYears(examYear);
        } catch (Exception e) {
            throw new CustomException(BizErrorCode.COM_E0004);
        }
        List<GradeAnalysisDataVo> lists = new ArrayList<>();
        for (String year : yearList) {
            List<GradeAnalysisDataVo> list = gradeAnalysisDataMapper.selectGradeAnalysisDataListByIdAndYear(examNameConfigId, year, AnalysisType.ANSLYSISE_TYPE_SEX.getCode(), examId);
            if (CollectionUtils.isNotEmpty(list)) {
                lists.addAll(list);
            }
        }
        return lists;
    }

    @Override
    public GradeAnalysisRsp selectGradeAnalysisData(QueryExamineeGradeVo queryExamineeGradeVo) {
        log.info("查询成绩分析信息begin...查询条件{}", JSON.toJSONString(queryExamineeGradeVo));
        GradeAnalysisRsp rsp = new GradeAnalysisRsp();
        String examNameConfigId = queryExamineeGradeVo.getExamNameConfigId();
        String examYear = queryExamineeGradeVo.getExamYear();
        String examId = queryExamineeGradeVo.getExamId();


        // 考试id不为空时是当前考试成绩总体概况。为空时是当年成绩总体概况
        GradeAnalysisDataVo curGradeAnalysisData = getYearDataVo(examNameConfigId, examYear, examId);

        if (null != curGradeAnalysisData) {
            convertCurYearData(curGradeAnalysisData, examNameConfigId, examYear, examId);
        }
        rsp.setCurDataAnalysis(curGradeAnalysisData);
        // 最近五年年份数据
        List<String> yearList = null;
        try {
            yearList = DateUtils.getLatestFiveYears(examYear);
        } catch (Exception e) {
            throw new CustomException(BizErrorCode.COM_E0004);
        }
        // 实考趋势和整体合格率趋势
        List<GradeAnalysisDataVo> totalDataList = gradeAnalysisDataMapper.selectGradeAnalysisDataListByIdAndYearList(examNameConfigId, yearList, AnalysisType.ANSLYSIS_TYPE_TOTAL.getCode(), examId);

        rsp.setTotalDataList(totalDataList);

        // 2.考试成绩分析

        // 科目合格率趋势
        List<GradeAnalysisDataVo> subjectDataList = gradeAnalysisDataMapper.selectGradeAnalysisDataListByIdAndYearList(examNameConfigId, yearList, AnalysisType.ANSLYSIS_TYPE_SUBJECT.getCode(), examId);
        if (CollectionUtils.isNotEmpty(subjectDataList)) {
            rsp.setSubjectDataMap(convertSubjectData(subjectDataList, examId, examNameConfigId));
        }
        // 年龄合格率趋势
        List<GradeAnalysisDataVo> ageDataList = gradeAnalysisDataMapper.selectGradeAnalysisDataListByIdAndYear(examNameConfigId, examYear,
                AnalysisType.ANSLYSIS_TYPE_AGE.getCode(), examId);
        if (CollectionUtils.isNotEmpty(ageDataList)) {
            ageDataList = convertAgeDict(ageDataList);
        }
        rsp.setAgeDataList(ageDataList);
        // 性别合格率趋势
        List<GradeAnalysisDataVo> sexDataList = gradeAnalysisDataMapper.selectGradeAnalysisDataListByIdAndYear(examNameConfigId, examYear, AnalysisType.ANSLYSISE_TYPE_SEX.getCode(), examId);
        rsp.setSexDataList(sexDataList);
        // 区域
        List<GradeAnalysisDataVo> areaDataList = gradeAnalysisDataMapper.selectGradeAnalysisDataListByIdAndYear(examNameConfigId, examYear, AnalysisType.ANSLYSIS_TYPE_AREA.getCode(), examId);
        rsp.setAreaDataList(areaDataList);
        log.info("查询成绩分析信息end...");
        return rsp;
    }

    private Map<String, List<GradeAnalysisDataVo>> convertSubjectData(List<GradeAnalysisDataVo> subjectDataList, String examId, String examNameId) {
        ExamSubjectNameConfig examSubjectNameConfig = new ExamSubjectNameConfig();
        examSubjectNameConfig.setExamNameId(examNameId);
        List<ExamSubjectNameConfig> examSubjectInfoList = subjectNameConfigMapper.selectExamSubjectNameConfigList(examSubjectNameConfig);
        //List<ExamSubjectVo> examSubjectInfoList = subjectInfoMapper.selectExamSubjectInfoByExamId(examId);
        if (CollectionUtils.isEmpty(examSubjectInfoList)) {
            throw new CustomException("未找到考试对应的科目信息");
        }
        Map<String, ExamSubjectNameConfig> map = examSubjectInfoList.stream().collect(Collectors.toMap(ExamSubjectNameConfig::getId, examSubjectInfo -> examSubjectInfo));
        Map<String, List<GradeAnalysisDataVo>> subjectDataMap = new LinkedHashMap<>();
        for (GradeAnalysisDataVo vo : subjectDataList) {
            if (null != map.get(vo.getSubjectId())) {
                vo.setSubjectName(map.get(vo.getSubjectId()).getName());
            }
            if (null != subjectDataMap.get(vo.getExamYear())) {
                subjectDataMap.get(vo.getExamYear()).add(vo);
            } else {
                List<GradeAnalysisDataVo> list = new ArrayList<>();
                list.add(vo);
                subjectDataMap.put(vo.getExamYear(), list);
            }
        }

        return subjectDataMap;
    }

    /**
     * 转换年龄区间段
     *
     * @param dataList
     */
    private List<GradeAnalysisDataVo> convertAgeDict(List<GradeAnalysisDataVo> dataList) {
        List<GradeAnalysisDataVo> returnList = new ArrayList<>();
        Map<String, String> ageMap = new HashMap<>();
        SysDictData sysDictData = new SysDictData();
        sysDictData.setDictType("sys_age_range");
        List<SysDictData> sysDictDataList = dictDataMapper.selectDictDataList(sysDictData);
        if (CollectionUtils.isNotEmpty(sysDictDataList)) {
            ageMap = sysDictDataList.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        }
        for (GradeAnalysisDataVo vo : dataList) {
            if (null != ageMap.get(vo.getAgeRange()) && vo.getPassNum() > 0) {
                String[] arr = ageMap.get(vo.getAgeRange()).split("-");
                if (arr.length > 1) {
                    vo.setAgeRangeName(ageMap.get(vo.getAgeRange()) + "岁");
                } else {
                    vo.setAgeRangeName(arr[0] + "岁以上");
                }
                returnList.add(vo);
            }
        }
        return returnList;
    }


    /**
     * 设置考试当前年份统计信息
     *
     * @param gradeAnalysisDataVo
     * @param examNameConfigId
     * @param examYear
     */
    @Override
    public void convertCurYearData(GradeAnalysisDataVo gradeAnalysisDataVo, String examNameConfigId,
                                   String examYear, String examId) {
        log.info("设置当前年份的整体数据");
        BigDecimal multi = new BigDecimal(100);

        GradeAnalysisDataVo lastGradeAnalysisData = null;
        GradeAnalysisDataVo beforeLastYearGradeAnalysisData = null;

        //  如果选择了考试，则获取最近两次次的考试信息
        if (StringUtils.isNotEmpty(examId)) {
            // 获取最近的两场考试信息
            List<GradeAnalysisDataVo> latestTwoExamInfo = gradeAnalysisDataMapper.selectLatestTwoExamInfo(examNameConfigId, examId);
            if (CollectionUtils.isNotEmpty(latestTwoExamInfo)) {
                lastGradeAnalysisData = latestTwoExamInfo.get(0);
                if (latestTwoExamInfo.size() > 1) {
                    beforeLastYearGradeAnalysisData = latestTwoExamInfo.get(1);
                }
            }

        } else {
            // 去年
            String lastYear = DateUtils.getLastYear(examYear);
            lastGradeAnalysisData = getYearDataVo(examNameConfigId, lastYear, examId);
            // 前年
            String beforeLastYear = DateUtils.getLastYear(lastYear);
            beforeLastYearGradeAnalysisData = getYearDataVo(examNameConfigId, beforeLastYear, examId);
        }

        // 计算去年增长率,报名人数、实考人数、合格人数、合格率
        // 报名人数增长率
        BigDecimal lastYearRegistrationGrowth = caculateGrowth(lastGradeAnalysisData, beforeLastYearGradeAnalysisData, "registrationNum");
        BigDecimal curYearRegistrationGrowth = caculateGrowth(gradeAnalysisDataVo, lastGradeAnalysisData, "registrationNum");
        gradeAnalysisDataVo.setRegistrationNumGrowth((curYearRegistrationGrowth.subtract(lastYearRegistrationGrowth)).multiply(multi).setScale(0, BigDecimal.ROUND_HALF_UP) + "%");
        // 实际考试人数环比增长率
        BigDecimal lastYearExamineeNumGrowth = caculateGrowth(lastGradeAnalysisData, beforeLastYearGradeAnalysisData, "examineeNum");
        BigDecimal curYearExamineeNumGrowth = caculateGrowth(gradeAnalysisDataVo, lastGradeAnalysisData, "examineeNum");
        gradeAnalysisDataVo.setExamineeNumGrowth((curYearExamineeNumGrowth.subtract(lastYearExamineeNumGrowth)).multiply(multi).setScale(0, BigDecimal.ROUND_HALF_UP) + "%");
        // 合格人数环比增长率
        BigDecimal lastYearPassNumGrowth = caculateGrowth(lastGradeAnalysisData, beforeLastYearGradeAnalysisData, "passNum");
        BigDecimal curYearPassNumGrowth = caculateGrowth(gradeAnalysisDataVo, lastGradeAnalysisData, "passNum");
        gradeAnalysisDataVo.setPassNumGrowth((curYearPassNumGrowth.subtract(lastYearPassNumGrowth)).multiply(multi).setScale(0, BigDecimal.ROUND_HALF_UP) + "%");
        // 合格率环比增长率
        BigDecimal lastYearPassRateGrowth = caculateGrowth(lastGradeAnalysisData, beforeLastYearGradeAnalysisData, "passRate");
        BigDecimal curYearPassRateGrowth = caculateGrowth(gradeAnalysisDataVo, lastGradeAnalysisData, "passRate");
        gradeAnalysisDataVo.setPassRateGrowth((curYearPassRateGrowth.subtract(lastYearPassRateGrowth)).multiply(multi).setScale(0, BigDecimal.ROUND_HALF_UP) + "%");

    }

    /**
     * 计算增长率，增长率(/降低率)＝(今年人数-去年人数)/去年人数，正数即为增长率，复数即为降低率
     *
     * @param curYearData
     * @param lastYearData
     * @return
     */
    private BigDecimal caculateGrowth(GradeAnalysisDataVo curYearData, GradeAnalysisDataVo lastYearData, String field) {
        BigDecimal growth = BigDecimal.ZERO;

        try {

            Field tmpField = GradeAnalysisDataVo.class.getDeclaredField(field);
            if (tmpField.getType() == Long.class) {
                long curYearAnalysisData = 0L;
                long lastYearAnalysisData = 0L;
                if (null != curYearData) {
                    Field curField = curYearData.getClass().getDeclaredField(field);
                    curField.setAccessible(true);
                    if (null != curYearData && null != curField.get(curYearData)) {
                        curYearAnalysisData = (Long) curField.get(curYearData);
                    }
                }
                if (null != lastYearData) {
                    Field lastField = lastYearData.getClass().getDeclaredField(field);
                    lastField.setAccessible(true);
                    if (null != lastYearData && null != lastField.get(lastYearData)) {
                        lastYearAnalysisData = (Long) lastField.get(lastYearData);
                    }
                }

                if (lastYearAnalysisData > 0) {
                    growth = new BigDecimal(curYearAnalysisData - lastYearAnalysisData).divide(new BigDecimal(lastYearAnalysisData), 2, BigDecimal.ROUND_HALF_UP);
                    //growth = new BigDecimal((curYearAnalysisData-lastYearAnalysisData)/lastYearAnalysisData).setScale(2,BigDecimal.ROUND_HALF_UP);
                }
            } else if (tmpField.getType() == BigDecimal.class) {
                BigDecimal cur = BigDecimal.ZERO;
                BigDecimal last = BigDecimal.ZERO;
                if (null != curYearData) {
                    Field curField = curYearData.getClass().getDeclaredField(field);
                    curField.setAccessible(true);
                    if (null != curYearData && null != curField.get(curYearData)) {
                        cur = (BigDecimal) curField.get(curYearData);
                    }
                }
                if (null != lastYearData) {
                    Field lastField = lastYearData.getClass().getDeclaredField(field);
                    lastField.setAccessible(true);
                    if (null != lastYearData && null != lastField.get(lastYearData)) {
                        last = (BigDecimal) lastField.get(lastYearData);
                    }
                }

                if (BigDecimal.ZERO.compareTo(last) != 0) {
                    growth = last.subtract(cur).divide(last, 2, BigDecimal.ROUND_HALF_UP);
                }
            }
        } catch (Exception e) {
            log.error("获取反射类字段报错", e);
            throw new CustomException("解析增长率报错");
        }

        return growth;
    }

    /**
     * 获取某一年份的考试统计信息
     *
     * @param examNameConfigId
     * @param examYear
     * @return
     */
    @Override
    public GradeAnalysisDataVo getYearDataVo(String examNameConfigId, String examYear, String examId) {
        GradeAnalysisDataVo vo = new GradeAnalysisDataVo();
        List<GradeAnalysisDataVo> curYearDataList = gradeAnalysisDataMapper.selectGradeAnalysisDataListByIdAndYear(examNameConfigId, examYear,
                AnalysisType.ANSLYSIS_TYPE_TOTAL.getCode(), examId);
        if (!CollectionUtils.isEmpty(curYearDataList)) {
            vo = curYearDataList.get(0);
        }
        return vo;
    }

    /**
     * 查询最近五年总体概况 ：实考趋势和整体合格率趋势
     *
     * @param examYear
     * @param examNameConfigId
     * @return
     */
    @Override
    public List<GradeAnalysisDataVo> selectGradeAnalysisDataTotalListByIdAndYearList(
            String examYear, String examNameConfigId, String examId) {
        // 最近五年年份数据
        List<String> yearList = null;
        try {
            yearList = DateUtils.getLatestFiveYears(examYear);
        } catch (Exception e) {
            throw new CustomException(BizErrorCode.COM_E0004);
        }
        // 实考趋势和整体合格率趋势
        return gradeAnalysisDataMapper.selectGradeAnalysisDataListByIdAndYearList(examNameConfigId, yearList, AnalysisType.ANSLYSIS_TYPE_TOTAL.getCode(), examId);
    }

    @Override
    public List<ExportAreaAnalysisDataVo> selectExportAreaDataList(ExportParamVo exportParamVo) {
        List<ExportAreaAnalysisDataVo> list = gradeAnalysisDataMapper.selectExportAreaDataList(exportParamVo);
        if (CollectionUtils.isNotEmpty(list)) {
            for (ExportAreaAnalysisDataVo dataVo : list) {
                DecimalFormat df = new DecimalFormat("0.00%");
                dataVo.setPercentExamRate(df.format(dataVo.getExamRate()));
                dataVo.setPercentPassRate(df.format(dataVo.getPassRate()));
            }
        }
        return list;
    }

    @Override
    public AjaxResult exportAnalysisData(ExportParamVo exportParamVo) {
        List<String> yearList = new ArrayList<>();
        try {
            yearList = DateUtils.getLatestFiveYears(exportParamVo.getExamYear());
        } catch (Exception e) {
            e.printStackTrace();
        }
        exportParamVo.setExamYearList(yearList);
        DecimalFormat df = new DecimalFormat("0.00%");
        if (ExportType.EXPORT_TYPE_SUBJECT.getCode().equals(exportParamVo.getExportType())) {
            List<ExportSubjectAnalysisDataVo> list = gradeAnalysisDataMapper.selectExportSubjectDataList(exportParamVo);
            if (CollectionUtils.isNotEmpty(list)) {
                for (ExportSubjectAnalysisDataVo dataVo : list) {
                    dataVo.setPercentPassRate(df.format(dataVo.getPassRate()));
                }
            }
            ExcelUtil<ExportSubjectAnalysisDataVo> util = new ExcelUtil<ExportSubjectAnalysisDataVo>(ExportSubjectAnalysisDataVo.class);
            return util.exportExcel(list, "考试成绩科目合格率数据分析数据", exportParamVo.getImageBase64());
        } else {
            List<ExportAnalysisDataBaseVo> list = gradeAnalysisDataMapper.selectExportRateDataList(exportParamVo);
            if (ExportType.EXPORT_TYPE_EXAM_RATE.getCode().equals(exportParamVo.getExportType())) {
                List<ExportExamRateAnalysisDataVo> exportList = new ArrayList<>();
                for (ExportAnalysisDataBaseVo vo : list) {
                    ExportExamRateAnalysisDataVo rateAnalysisDataVo = new ExportExamRateAnalysisDataVo();
                    BeanUtils.copyProperties(vo, rateAnalysisDataVo);
                    rateAnalysisDataVo.setPercentExamRate(df.format(vo.getExamRate()));
                    exportList.add(rateAnalysisDataVo);
                }
                ExcelUtil<ExportExamRateAnalysisDataVo> util = new ExcelUtil<ExportExamRateAnalysisDataVo>(ExportExamRateAnalysisDataVo.class);
                return util.exportExcel(exportList, "考试成绩实考率数据分析数据", exportParamVo.getImageBase64());
            } else {
                List<ExportPassRateAnalysisDataVo> exportList = new ArrayList<>();
                for (ExportAnalysisDataBaseVo vo : list) {
                    ExportPassRateAnalysisDataVo rateAnalysisDataVo = new ExportPassRateAnalysisDataVo();
                    BeanUtils.copyProperties(vo, rateAnalysisDataVo);
                    rateAnalysisDataVo.setPercentPassRate(df.format(vo.getPassRate()));
                    exportList.add(rateAnalysisDataVo);
                }
                ExcelUtil<ExportPassRateAnalysisDataVo> util = new ExcelUtil<ExportPassRateAnalysisDataVo>(ExportPassRateAnalysisDataVo.class);
                return util.exportExcel(exportList, "考试成绩合格率数据分析数据", exportParamVo.getImageBase64());
            }
        }
    }
}